package com.smartleanx.module.hrm.controller.app.salarynotice;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.smartleanx.framework.common.enums.BizTypeEnum;
import com.smartleanx.framework.common.pojo.CommonResult;
import com.smartleanx.framework.common.pojo.PageResult;
import com.smartleanx.framework.common.util.collection.CollectionUtils;
import com.smartleanx.framework.common.util.object.BeanUtils;
import com.smartleanx.framework.customfield.core.service.CustomFieldDataService;
import com.smartleanx.framework.customfield.core.service.bo.CustomFieldDataListReqBO;
import com.smartleanx.framework.customfield.core.service.bo.CustomFieldDataRespBO;
import com.smartleanx.module.hrm.context.EmployeeContextHolder;
import com.smartleanx.module.hrm.controller.app.salarynotice.vo.AppSalaryNoticePageReqVO;
import com.smartleanx.module.hrm.controller.app.salarynotice.vo.AppSalaryNoticeRespVO;
import com.smartleanx.module.hrm.controller.app.salarynotice.vo.AppSalaryNoticeSaveReqVO;
import com.smartleanx.module.hrm.dal.dataobject.employee.EmployeeDO;
import com.smartleanx.module.hrm.dal.dataobject.payroll.PayrollDO;
import com.smartleanx.module.hrm.dal.dataobject.payroll.PayrollDetailDO;
import com.smartleanx.module.hrm.dal.dataobject.salarynotice.SalaryNoticeDO;
import com.smartleanx.module.hrm.eums.employee.EmployeeStatusEnum;
import com.smartleanx.module.hrm.eums.payroll.PayrollStateEnum;
import com.smartleanx.module.hrm.service.employee.EmployeeService;
import com.smartleanx.module.hrm.service.payroll.PayrollDetailService;
import com.smartleanx.module.hrm.service.payroll.PayrollService;
import com.smartleanx.module.hrm.service.salarynotice.SalaryNoticeService;
import com.smartleanx.module.system.enums.customfield.CustomFieldLabelEnum;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.smartleanx.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.smartleanx.framework.common.pojo.CommonResult.success;
import static com.smartleanx.module.hrm.enums.ErrorCodeConstants.SALARY_NOTICE_EMPLOYEE_UNBIND;

@Tag(name = "用户 APP - 员工工资条通知")
@RestController
@RequestMapping("/hrm/salary-notice")
@Validated
public class AppSalaryNoticeController {

    @Resource
    private SalaryNoticeService salaryNoticeService;

    @Resource
    private PayrollDetailService payrollDetailService;

    @Resource
    private PayrollService payrollService;

    @Resource
    private CustomFieldDataService customFieldDataService;

    @Resource
    private EmployeeService employeeService;

    @PutMapping("/update")
    @Operation(summary = "更新员工工资条通知(确认、对工资有疑问)")
    public CommonResult<Boolean> updateNotice(@Valid @RequestBody AppSalaryNoticeSaveReqVO updateReqVO) {
        salaryNoticeService.updateNotice(updateReqVO);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得员工工资条通知(查看)")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    public CommonResult<List<CustomFieldDataRespBO>> getSalaryNotice(@RequestParam("id") Long id) {
        SalaryNoticeDO salaryNotice = salaryNoticeService.getNotice(id);
        if(Objects.isNull(salaryNotice)){
            return success(Collections.emptyList());
        }
        PayrollDetailDO detail = payrollDetailService.getDetail(salaryNotice.getPayrollDetailId());
        if(Objects.isNull(detail)){
            return success(Collections.emptyList());
        }
        PayrollDO payroll = payrollService.getPayroll(detail.getPayrollId());
        if(Objects.isNull(payroll)){
            return success(Collections.emptyList());
        }
        CustomFieldDataListReqBO reqBO = CustomFieldDataListReqBO.builder().bizType(BizTypeEnum.PAYROLL.getValue())
                .labels(CollUtil.newArrayList(CustomFieldLabelEnum.PAYROLL_EMPLOYEE_INFO.getValue(), CustomFieldLabelEnum.PAYROLL_DETAIL_INFO.getValue()))
                .recordIds(Collections.singletonList(salaryNotice.getId())).edition(BizTypeEnum.PAYROLL_SALARY_NOTICE.getValue())
                .version(PayrollStateEnum.ARCHIVE.getValue().equals(payroll.getState())? payroll.getId(): 0).build();
        List<CustomFieldDataRespBO> fieldDataList = customFieldDataService.getDataList(reqBO);
        EmployeeDO employee = employeeService.getEmployeeById(salaryNotice.getEmployeeId());
        Map<String, Object> noticeMap = BeanUtil.beanToMap(salaryNotice);
        if(Objects.nonNull(employee)){
            noticeMap.put("employeeNo", employee.getEmployeeNo());
            noticeMap.put("employeeDeptId", employee.getDeptId());
            noticeMap.put("employeePostId", employee.getPostId());
            noticeMap.put("employeePostLevelId", employee.getPostLevelId());
            noticeMap.put("employeeState", EmployeeStatusEnum.getName(employee.getState()));
        }
        List<CustomFieldDataRespBO>  respBOs = CollectionUtils.convertList(fieldDataList, fieldData -> {
            String key = StringUtils.underlineToCamel(fieldData.getColName());
            if(noticeMap.containsKey(key)){
                fieldData.setFieldValue(Objects.toString(noticeMap.get(key)));
            }
            return fieldData;
        });
        CollectionUtils.filterList(respBOs, fieldData -> StringUtils.isNotEmpty(fieldData.getFieldValue()));
        customFieldDataService.parseData(reqBO, respBOs);
        return success(respBOs);
    }

    @GetMapping("/page")
    @Operation(summary = "获得员工工资条通知分页(我的工资条)")
    public CommonResult<PageResult<AppSalaryNoticeRespVO>> getNoticePage(@Valid AppSalaryNoticePageReqVO pageReqVO) {
        Long employeeId = EmployeeContextHolder.getEmployeeId();
        if(Objects.isNull(employeeId)){
            throw exception(SALARY_NOTICE_EMPLOYEE_UNBIND);
        }
        pageReqVO.setEmployeeId(employeeId);
        PageResult<SalaryNoticeDO> pageResult = salaryNoticeService.getNoticePage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, AppSalaryNoticeRespVO.class));
    }

}